// const { resolveApp } = require('./utils');

class DynamicPublicPathPlugin {
  /**
   * 增加一个webpack plugin，在Webpack hook中动态修改publicPath
   * 这是为了在编译和运行时区分publicPath
   * 编译时需要publicPath为绝对路径，保证html中加载js时不出错
   * 运行时，特别是mf在加载远程文件时，远程文件本身在加载js时，需要publicPath为自己的域名
   * TODO 目前只解决了开发环境，需要解决生产环境。
   * 见： https://github.com/module-federation/module-federation-examples/issues/102
   * @parem {Object} compiler - The Webpack compiler.
   */
  apply(compiler) {
    compiler.hooks.make.tap('MutateRuntime', (compilation) => {
      compilation.hooks.runtimeModule.tap('MutateRuntime', (module, chunk) => {
        const isPublicPathRuntimeModule = module.constructor.name === 'PublicPathRuntimeModule';
        if (!isPublicPathRuntimeModule) {
          return;
        }

        console.log(`* Update "${chunk.name}" dynamic public path`);

        // 提取变量“ key”（等号左侧的名称空间）
        // 丢掉后面的部分，因为我们要创建一个新的值并代替它
        const [key, val] = module.getGeneratedCode().split('=');

        // 替换将在浏览器session中运行的函数的旧的静态字符串值
        // 并根据当前配置创建公共路径。
        //
        // 注意这个地方，我们需要在要引入其它运行时js的库内去配置正确的publicPath前缀
        // 目前是在入口文件(index.tsx)中去读取config.js中配置的remotes
        // 然后以package.json中的工程名作为key，部署的域名作为value存放在window对象的__LOCATION__变量中
        // 如果没获取到__LOCATION__变量，则表示应用没有运行时配置publicPath的需要，返回原来的配置即可
        // 预留一个__ENVIRONEMENT__变量，用于将来可能的对于不同的环境的处理

        // const packageName = require(`${resolveApp('')}/package.json`).name;

        const _cachedGeneratedCode = `${key}=(function() {
          const   __SY_STATIC_FILE_ORIGIN__ = window.__SY_STATIC_FILE_ORIGIN__ || null;
          const   __SY_STATIC_API_ORIGIN__ = window.__SY_STATIC_API_ORIGIN__  || null;
          var val = ${val};
          return __SY_STATIC_FILE_ORIGIN__ ? __SY_STATIC_FILE_ORIGIN__ + val : ${val}
        })();`;

        //TODO 生产环境需要解决
        module._cachedGeneratedCode = _cachedGeneratedCode;

        return module;
      });
    });
  }
}

module.exports = DynamicPublicPathPlugin;
